﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using Extentions;
using Microsoft.AspNetCore.Http;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using TrainingReminderSystem.Dal;
using TrainingReminderSystem.Model;

namespace TrainingReminderSystem.Bll
{
    /// <summary>
    /// 员工表信息表逻辑层
    /// </summary>
    public partial class SysEmployeeBll : PcLoginedBll
    {
        #region 添加和编辑的时候 验证数据和设置默认值

        /// <summary>
        /// 添加和编辑的时候 验证数据和设置默认值
        /// </summary>
        /// <param name="db"></param>
        /// <param name="model"></param>
        /// <param name="isAdd">添加还是编辑,可以不管此参数</param>
        /// <returns>是否通过,true表示验证通过,false代表验证没有通过</returns>
        public AjaxResult<dynamic> Validate(DbEntities db, SysEmployee model, bool isAdd)
        {
            var r = new AjaxResult<dynamic>();
            if (model == null)
            {
                r.Message = LanguageHelper.NoSubmitData;
                return r;
            }
            model.SysEmployeeName = model.SysEmployeeName.ExTrim();
            if (string.IsNullOrEmpty(model.SysEmployeeName))
            {
                r.Message = "请输入员工姓名!";
                return r;
            }
            model.PY = ToolHelper.GetPy(model.SysEmployeeName);

            if (string.IsNullOrEmpty(model.SysEmployeePhone))
            {
                r.Message = "请输入员工手机号码";
                return r;
            }
            model.SysEmployeePhone = model.SysEmployeePhone.ExTrim();

            var currentStore = CurrentStore;
            if (currentStore.IsAdminStore() || currentStore.IsMainStore())
            {
                if (model.TempSysStoreID == null || model.TempSysStoreID.Value <= 0)
                {
                    r.Message = "请选择店铺";
                    return r;
                }

                if (currentStore.IsAdminStore() == false)
                {
                    var allStoreID = GetAllStoreIDCache(currentStore.SysStoreID, db);
                    if (allStoreID.Contains(model.TempSysStoreID.Value) == false)
                    {
                        r.Message = "所选店铺有误";
                        return r;
                    }
                }
            }
            //新增的时候,子店铺默认就是自己的店铺ID,如果是主店铺,就可以选择店铺ID;修改的时候,子店铺不能更改所属店铺
            if (isAdd)
            {
                if (currentStore.IsMainStore() == false)
                {
                    model.TempSysStoreID = currentStore.SysStoreID;
                }
            }
            if (!string.IsNullOrEmpty(model.UserCode))
            {
                model.UserCode = model.UserCode.ExTrim();
            }
            else
            {
                model.UserCode = string.Empty;
            }

            if (model.SysOperator == null) model.SysOperator = model.Operator;
            var opModel = model.SysOperator;
            opModel.LoginPwd = string.Empty;
            opModel.EnumStatus = EnumStatus.启用;
            //新增有登录密码的判断
            opModel.UpdateDate = DateTime.Now;
            var currentEmployee = CurrentEmployee;
            if (currentEmployee == null)
            {
                r.Message = "调用错误,只允许PC端调用";
                return r;
            }
            model.SysEmployeeStoreRelation = new List<SysEmployeeStoreRelation>()
            {
                new SysEmployeeStoreRelation()
                {
                    CreateDate = DateTime.Now,
                    CreateSysEmployeeID = CurrentEmployee?.SysEmployeeID,
                    ID = 0,
                    Remark = null,
                    SysEmployee = null,
                    SysEmployeeID = model.SysEmployeeID,
                    SysStore = null,
                    SysStoreID = model.TempSysStoreID.Value
                }
            };
            //同一家店铺的员工手机号,不允许相同;但是不同子店铺的员工的手机号允许相同;这里要拉出店铺的所有店铺ID,然后从没有Filter里的数据里去判断; UserCode是店铺唯一(admin店铺和非admin店铺的区别而已)
            var dbNoFilter = DbNoFilter;
            var hasPhone = dbNoFilter.SysEmployee.AsNoTracking().Any(m =>
                m.SysEmployeeID != model.SysEmployeeID && m.SysEmployeePhone == model.SysEmployeePhone &&
                m.SysEmployeeStoreRelation.Any(n => n.SysStoreID == model.TempSysStoreID));
            if (hasPhone)
            {
                r.Message = "同一店铺下,已存在此手机号,请核查";
                return r;
            }
            if (!string.IsNullOrEmpty(model.UserCode))
            {
                //判断唯一
                var hasUserCode = dbNoFilter.SysEmployee.AsNoTracking().Any(m => m.UserCode == model.UserCode && m.SysEmployeeID != model.SysEmployeeID);
                if (hasUserCode)
                {
                    r.Message = "此登录帐号已经存在,请换一个";
                    return r;
                }
            }

            model.UpdateSysEmployeeID = currentEmployee.SysEmployeeID;
            opModel.UpdateSysEmployeeID = currentEmployee.SysEmployeeID;

            model.SysRolePostEmployeeRelation = null;//编辑的时候会是空对象
            if (model.SysRoles != null)
            {
                model.SysRolePostEmployeeRelation = new List<SysRolePostEmployeeRelation>();
                foreach (var item in model.SysRoles)
                {
                    SysRolePostEmployeeRelation relation = new SysRolePostEmployeeRelation
                    {
                        CreateDate = DateTime.Now,
                        CreateSysEmployeeID = currentEmployee.SysEmployeeID,
                        SysEmployeeID = model.SysEmployeeID,
                        SysRolePostID = item
                    };
                    model.SysRolePostEmployeeRelation.Add(relation);
                }
            }
            model.UpdateDate = DateTime.Now;
            r.Success = true;
            return r;
        }

        #endregion

        #region 分页方法

        /// <summary>
        /// 查询条件,能替换掉一些属性查询为自定义查询
        /// </summary>
        /// <param name="where"></param>
        /// <param name="key"></param>
        /// <param name="val"></param>
        /// <returns></returns>
        public Expression<Func<SysEmployee, bool>> InitSearchDelegete(Expression<Func<SysEmployee, bool>> where,
            string key, string val)
        {
            if (key == "SelectID")
            {
                int tempID = val.ExToInt32();
                return where.ExAnd(m => m.SysEmployeeID == tempID);
            }

            return null;
        }

        /// <summary>
        /// 分页方法
        /// </summary>
        /// <param name="index"></param>
        /// <param name="size"></param>
        /// <param name="form"></param>
        /// <param name="sortField"></param>
        /// <param name="asc"></param>
        /// <returns></returns>
        public AjaxResult<dynamic> GetListByPage(int index, int size, IFormCollection form = null, string sortField = "", bool asc = false)
        {
            using (var db = Db)
            {
                Expression<Func<SysEmployee, bool>> where = InitSearch<SysEmployee>(form, InitSearchDelegete); //拼接查询条件方法

                #region 拼接查询条件

                if (form != null)
                {
                }

                #endregion

                int counts;
                var tempIDList = db.SysEmployee.ExOrderBy(sortField, asc).ExGetListByPage(index, size, out counts, where).Select(m => m.SysEmployeeID);
                var result = new AjaxResult<dynamic>() { Success = true };
                result.Total = counts;
                IQueryable<SysEmployee> list = db.SysEmployee.Where(m => tempIDList.Contains(m.SysEmployeeID)).ExOrderBy(sortField, asc);
                var tempList = list.Select(m => new
                {
                    SysEmployeeID = m.SysEmployeeID,
                    EnumQuitStatus = m.EnumQuitStatus,
                    SysEmployeeName = m.SysEmployeeName,
                    PY = m.PY,
                    SysEmployeePhone = DbFun.fn_replaceNum(m.SysEmployeePhone, CanSeePhone),
                    UserCode = m.UserCode,
                    UpdateEmployeeID = m.UpdateSysEmployeeID,
                    UpdateDate = m.UpdateDate,
                    m.CanSeePhone,
                    m.IsDemo,
                    IsDel = m.IsDel,
                    Remark = m.Remark,
                    HeaderUrl = m.HeaderUrl,

                    SysStore = m.SysEmployeeStoreRelation.Select(n => new
                    {
                        n.SysStore.SysStoreID,
                        n.SysStore.SysStoreName,
                    }).FirstOrDefault(),
                    SysOperator = m.SysOperator,
                    LastDate = db.SysLog.OrderByDescending(n => n.ID).FirstOrDefault(n =>
                        n.EnumLogType == EnumLogType.登录 && n.SysEmployeeID == m.SysEmployeeID).CreateDate
                });
                result.Result = tempList.ToList();
                return result;
            }
        }

        #endregion

        #region 得到单对象,返回值有可能为null

        /// <summary>
        /// 得到单对象,返回值有可能为null
        /// </summary>
        /// <param name="id">主键值</param>
        /// <returns></returns>
        public AjaxResult<dynamic> GetModel(int id)
        {
            using (var db = Db)
            {
                var r = db.SysEmployee.Include(m => m.SysOperator).FirstOrDefault(m => m.SysEmployeeID == id);
                if (r.SysOperator == null)
                {
                    r.SysOperator = new SysOperator()
                    {
                        EnumStatus = EnumStatus.启用
                    };
                }
                else
                {
                    r.SysOperator.LoginPwd = string.Empty;
                }
                r.Operator = r.SysOperator;
                r.SysOperator = null;
                r.SysRoles = db.SysRolePostEmployeeRelation.Where(m => m.SysEmployeeID == id)
                    .Select(m => m.SysRolePostID).ToList();
                r.TempSysStoreID = db.SysEmployeeStoreRelation.Where(m => m.SysEmployeeID == id)
                    .Select(m => (int?)m.SysStoreID).FirstOrDefault();
                return AjaxResult<dynamic>.SuccessResult(r);
            }
        }

        #endregion

        #region 保存数据

        /// <summary>
        /// 保存数据
        /// </summary>
        /// <param name="model">保存的对象,成功之后model对象的SysEmployeeID能得到SysEmployeeID</param>
        /// <returns></returns>
        public AjaxResult<dynamic> Save(SysEmployee model)
        {
            using (var db = Db)
            {
                if (model.SysEmployeeID <= 0)
                {
                    return this.Add(model, db);
                }
                return this.Update(model, db);
            }
        }

        #endregion

        #region 添加数据

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="model">添加的对象,成功之后model对象的SysEmployeeID能得到SysEmployeeID</param>
        /// <returns></returns>
        public AjaxResult<dynamic> Add(SysEmployee model)
        {
            using (var db = Db)
            {
                return this.Add(model, db);
            }
        }

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="model">添加的对象,成功之后model对象的SysEmployeeID能得到SysEmployeeID</param>
        /// <param name="db"></param>
        /// <returns></returns>
        internal AjaxResult<dynamic> Add(SysEmployee model, DbEntities db)
        {
            var r = new AjaxResult<dynamic>() { Success = false };
            if (db == null) db = Db;
            var tempAr = Validate(db, model, true);
            if (tempAr.Success == false)
            {
                r.Message = tempAr.Message;
                r.Result = tempAr.Result;
                r.Total = tempAr.Total;
                return r;
            }
            IDbContextTransaction tran = db.Database.CurrentTransaction;
            bool hasTran = tran != null;
            if (hasTran == false) tran = db.Database.BeginTransaction();
            try
            {
                db.SysEmployee.Add(model);
                string error = AddLog(db, model, EnumLogType.新建);
                if (!string.IsNullOrEmpty(error))
                {
                    return AjaxResult<dynamic>.ErrorResult(error);
                }
                bool isSuccess = db.SaveChanges() >= 0;
                if (hasTran == false)
                {
                    tran.Commit();
                    tran.Dispose();
                    tran = null;
                }
                r.Success = isSuccess;
                r.Message = isSuccess ? "添加成功" : "添加失败,请重试!";
                r.Result = model.SysEmployeeID;
                return r;
            }
            catch (Exception ex)
            {
                ex.ExLogError(GetCurrentOther());
                r.Total = (int)EnumTotal.异常;
                r.Success = false;
                r.Message = "新增失败:" + ex.ExMessageWithInner();
                return r;
            }
            finally
            {
                if (hasTran == false && tran != null) tran.Rollback();
            }
        }

        #endregion

        #region 编辑

        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="model">添加的对象,成功之后model对象的SysEmployeeID能得到SysEmployeeID</param>
        /// <returns></returns>
        public AjaxResult<dynamic> Update(SysEmployee model)
        {
            using (var db = Db)
            {
                return this.Update(model, db);
            }
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="model">添加的对象,成功之后model对象的SysEmployeeID能得到SysEmployeeID</param>
        /// <param name="db"></param>
        /// <returns></returns>
        internal AjaxResult<dynamic> Update(SysEmployee model, DbEntities db)
        {
            if (CurrentEmployee != null && CurrentEmployee.IsDemo)
            {
                return AjaxResult<dynamic>.ErrorResult("试用帐号不能更改用户信息");
            }
            var r = new AjaxResult<dynamic>() { Success = false };
            if (db == null) db = Db;
            var tempAr = Validate(db, model, false);
            if (tempAr.Success == false)
            {
                r.Message = tempAr.Message;
                r.Result = tempAr.Result;
                r.Total = tempAr.Total;
                return r;
            }
            IDbContextTransaction tran = db.Database.CurrentTransaction;
            bool hasTran = tran != null;
            if (hasTran == false) tran = db.Database.BeginTransaction();
            try
            {
                var beforeModel = db.SysEmployee.FirstOrDefault(m => m.SysEmployeeID == model.SysEmployeeID);
                if (beforeModel == null)
                {
                    r.Message = LanguageHelper.NoData;
                    return r;
                }
                beforeModel.EnumQuitStatus = model.EnumQuitStatus;
                beforeModel.SysEmployeeName = model.SysEmployeeName;
                beforeModel.PY = model.PY;
                beforeModel.SysEmployeePhone = model.SysEmployeePhone;
                beforeModel.UserCode = model.UserCode;
                beforeModel.UpdateSysEmployeeID = model.UpdateSysEmployeeID;
                beforeModel.UpdateDate = model.UpdateDate;
                //beforeModel.IsDel = model.IsDel;
                beforeModel.Remark = model.Remark;
                beforeModel.HeaderUrl = model.HeaderUrl;
                beforeModel.CanSeePhone = model.CanSeePhone;
                //beforeModel.SysOperator = model.SysOperator;
                //beforeModel.SysRolePostEmployeeRelation = model.SysRolePostEmployeeRelation;
                //处理操作员信息
                var op = db.SysOperator.FirstOrDefault(m => m.SysOperatorID == beforeModel.SysOperatorID);
                if (op == null)
                {
                    db.SysOperator.Add(model.SysOperator);
                    db.SaveChanges();
                    beforeModel.SysOperatorID = model.SysOperator.SysOperatorID;
                }
                else
                {
                    var sysOperator = model.SysOperator;
                    //op.SysOperatorID = sysOperator.SysOperatorID;
                    //op.LoginPwd = sysOperator.LoginPwd;
                    //op.OperatorPower = sysOperator.OperatorPower;
                    op.EnumStatus = sysOperator.EnumStatus;
                    op.UpdateSysEmployeeID = sysOperator.UpdateSysEmployeeID;
                    op.UpdateDate = sysOperator.UpdateDate;
                    //op.Remark = sysOperator.Remark;
                }

                if (beforeModel.EnumQuitStatus != model.EnumQuitStatus)
                {
                    if (beforeModel.SysEmployeeID == CurrentEmployee.SysEmployeeID)
                    {
                        r.Message = "员工不能更改自己的在职状态";
                        return r;
                    }
                }
                db.SaveChanges();

                if (CurrentStore.IsMainStore() || CurrentStore.IsAdminStore())
                {
                    var storeRelation =
                        db.SysEmployeeStoreRelation.FirstOrDefault(m => m.SysEmployeeID == beforeModel.SysEmployeeID);
                    if (storeRelation == null)
                    {
                        db.SysEmployeeStoreRelation.Add(model.SysEmployeeStoreRelation.FirstOrDefault());
                        db.SaveChanges();
                    }
                    else
                    {
                        var first = model.SysEmployeeStoreRelation.FirstOrDefault();
                        storeRelation.SysStoreID = first.SysStoreID;
                        db.SaveChanges();
                    }
                }

                db.SysRolePostEmployeeRelation.RemoveRange(db.SysRolePostEmployeeRelation.Where(m => m.SysEmployeeID == beforeModel.SysEmployeeID));
                if (model.SysRolePostEmployeeRelation != null && model.SysRolePostEmployeeRelation.Count > 0)
                {
                    db.SysRolePostEmployeeRelation.AddRange(model.SysRolePostEmployeeRelation);
                }

                string error = AddLog(db, model, EnumLogType.编辑);
                if (!string.IsNullOrEmpty(error))
                {
                    return AjaxResult<dynamic>.ErrorResult(error);
                }
                var isSuccess = db.SaveChanges() >= 0;
                if (hasTran == false)
                {
                    tran.Commit();
                    tran.Dispose();
                    tran = null;
                }

                //清理此员工的缓存
                ClearCache(model.SysEmployeeID);

                r.Success = isSuccess;
                r.Message = isSuccess ? "编辑成功" : "编辑失败,请重试!";
                r.Result = model.SysEmployeeID;
                return r;
            }
            catch (Exception ex)
            {
                ex.ExLogError(GetCurrentOther());
                r.Total = (int)EnumTotal.异常;
                r.Success = false;
                r.Message = "编辑失败:" + ex.ExMessageWithInner();
                return r;
            }
            finally
            {
                if (hasTran == false && tran != null) tran.Rollback();
            }
        }

        #endregion

        #region 删除

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public AjaxResult<dynamic> Del(int id)
        {
            using (var db = Db)
            {
                return Del(id, db);
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        internal AjaxResult<dynamic> Del(int id, DbEntities db)
        {
            var r = new AjaxResult<dynamic>() { Success = false };
            if (db == null) db = Db;
            IDbContextTransaction tran = db.Database.CurrentTransaction;
            bool hasTran = tran != null;
            if (hasTran == false) tran = db.Database.BeginTransaction();
            try
            {
                var beforeModel = db.SysEmployee.FirstOrDefault(m => m.SysEmployeeID == id);
                if (beforeModel == null)
                {
                    r.Message = LanguageHelper.NoData;
                    return r;
                }
                beforeModel.IsDel = true;
                string error = AddLog(db, new SysEmployee() { SysEmployeeID = id }, EnumLogType.删除);
                if (!string.IsNullOrEmpty(error))
                {
                    return AjaxResult<dynamic>.ErrorResult(error);
                }
                var isSuccess = db.SaveChanges() >= 0;
                if (hasTran == false)
                {
                    tran.Commit();
                    tran.Dispose();
                    tran = null;
                }
                r.Success = isSuccess;
                r.Message = isSuccess ? "删除成功" : "删除失败,请重试!";
                return r;
            }
            catch (Exception ex)
            {
                ex.ExLogError(GetCurrentOther());
                r.Total = (int)EnumTotal.异常;
                r.Success = false;
                r.Message = "删除失败:" + ex.ExMessageWithInner();
                return r;
            }
            finally
            {
                if (hasTran == false && tran != null)
                {
                    tran.Rollback();
                    tran.Dispose();
                }
            }
        }

        #endregion

        #region 得到员工下拉

        public AjaxResult<dynamic> GetListSelect(IFormCollection form)
        {
            using (var db = Db)
            {
                Expression<Func<SysEmployee, bool>> where = InitSearch<SysEmployee>(form, InitSearchDelegete); //拼接查询条件方法
                var selectID = form["selectIDName"].ExTrim();
                var obj = db.SysEmployee.AsNoTracking();
                bool hasSelectID = false;
                if (!string.IsNullOrEmpty(selectID))
                {
                    if (selectID.IndexOf(',') != -1)
                    {
                        var selectIDList = selectID.ExToSplitList();
                        if (selectIDList.Count > 0)
                        {
                            hasSelectID = true;
                            obj = obj.OrderByDescending(m => selectIDList.Contains(m.SysEmployeeID))
                                .ThenByDescending(m => m.SysEmployeeID);
                        }
                    }
                    else
                    {
                        var selectIDInt = selectID.ExToInt32();
                        if (selectIDInt > 0)
                        {
                            hasSelectID = true;
                            obj = obj.OrderByDescending(m => selectIDInt == m.SysEmployeeID)
                                .ThenByDescending(m => m.SysEmployeeID);
                        }
                    }
                    if (hasSelectID == false)
                    {
                        where = where.ExAnd(m => m.SysEmployeeName.Contains(selectID) || m.PY.Contains(selectID));
                    }
                }
                if (hasSelectID == false)
                {
                    obj = obj.OrderByDescending(m => m.SysEmployeeID);
                    where = where.ExAnd(m => m.EnumQuitStatus == EnumQuitStatus.在职);
                    //where = where.ExAnd(m => m.Operator == null || m.Operator.EnumStatus == EnumStatus.启用);
                }
                var result = new AjaxResult<dynamic>() { Success = true };
                var list = obj.Where(where).Take(DefaultSize);
                var tempList = list.Select(m => new
                {
                    m.SysEmployeeID,
                    m.SysEmployeeName,
                    m.SysEmployeePhone,
                    SysStoreName = m.SysEmployeeStoreRelation.FirstOrDefault().SysStore.SysStoreName
                });
                result.Result = tempList.ToList();
                return result;
            }
        }

        #endregion
    }
}
